home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *sccsid = "@(#)page.c 1.4 MS/ACF 89/05/08";
- #endif
-
- /*
- * tip/page.c (Douglas Kingston, Morgan Stanley & Co.)
- *
- * This file contains code to send alphanumeric pages via
- * dialup paging services that support "Remote Entry Device
- * Protocol" (aka "IXO"). These services typically send to
- * devices like the Motorola PMR-2000 pager.
- *
- * This module is designed to use the ACK/NAK packet protocol
- * to ensure the highest likelyhood of correct delivery of the
- * message. The packets are checksummed and all messages are
- * acknowledged by the receiver.
- *
- * To use this facility, tip must be called with the -p option,
- * a system name (what system to dial up) and finally a data
- * string which contains 3 items: A login code/password, a list
- * pager id's to receive the message, and the message text.
- * The three fields are separated by tabs. The pager id field
- * is further subdivided into a list of pager ids by commas.
- *
- * For example:
- * tip -p metro "12345678\t20001,20002\tPlease call the office."
- *
- * Would call the system called "metro" as listed in /etc/remote
- * and login with the ID 12345678. The message "Please call
- * the office." would be sent to pagers 20001 and 20002.
- *
- * This code has been tested only on the Metromedia Paging Services
- * system around New York City, though it should work on other
- * similiar systems.
- *
- * Douglas Kingston
- * Morgan Stanley & Co. (19th Floor)
- * 1251 Avenue of the Americas
- * NY, NY, 10020
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <signal.h>
- #include <sys/time.h>
- #include "tip.h"
-
- #define STX 002
- #define ETX 003
- #define EOT 004
- #define ACK 006
- #define NAK 025
- #define ETB 027
- #define ESC 033
- #define RS 036
-
- extern int vflag, FD;
- extern jmp_buf jmpbuf;
-
- extern char *strchr();
- extern int recvtimeout();
-
- char inbuf[270];
- char mbuf[32];
- char packet[270];
-
- static char *addstr();
-
- sendpage(data)
- char *data;
- {
- int ret = 1;
- int trys, i;
- char *cp, *pager, *message;
-
- if (boolean(value(VERBOSE)))
- vflag++;
- if (vflag)
- fputs("[Connected]\n", stderr);
-
- cp = data;
- if (pager = strchr(data, '\t')) {
- *pager = 0;
- pager++;
- } else {
- fprintf(stderr, "Bad paging data: '%s'\n", data);
- return(1);
- }
-
- trys = 0;
- do {
- if (trys++ > 3) {
- fprintf(stderr, "ID= retries failed\n");
- goto done;
- }
- if (pgsend("\r"))
- return(1);
- } while (pgrecv("ID=", 5) < 3);
-
- trys = 0;
- login_again:
-
- if (pgsend("\033") || pgsend(cp) || pgsend("\r"))
- return(1);
-
- /* Wait for ACK, NAK, EOT or Ready(?) */
- if (pgrecv("\r", 10) <= 0) {
- fprintf(stderr, "login timeout\n");
- goto done;
- }
- switch(inbuf[0]) {
- default: if (trys++ < 4) goto login_again; else goto done;
- case ACK: break;
- case NAK: if (trys++ < 4) goto login_again; else goto done;
- case RS: fprintf(stderr, "login got RS\n"); goto done;
- case ESC:
- switch(inbuf[1]) {
- case EOT: goto done;
- case '[': if(inbuf[2] == 'p') break;
- default: fprintf(stderr, "got unknown ESC code\n");
- goto login_again;
- }
- }
- pgrecv("\r", 10); /* Swallow Go Ahead <ESC>[p */
-
- if (message = strchr(pager, '\t')) {
- *message = 0;
- message++;
- } else
- message = "[Message not specified]";
- next_pager:
- if (cp = strchr(pager, ','))
- *cp++ = 0;
- buildpkt(pager, message);
-
- trys = 0;
- resend:
- if (pgsend(packet))
- return(1);
- pgrecv("^C\r\n", 10); /* ^C\r\n */
-
- /* Wait for ACK, NAK, EOT or Ready(?) */
- if ((i = pgrecv("\r", 10)) <= 0) {
- fprintf(stderr, "page send no reply\n");
- goto done;
- }
- switch(inbuf[i-2]) {
- default: fprintf(stderr, "page send reply error\n");
- goto done;
- case ACK: ret = 0; goto sent;
- case NAK: if (trys++ < 4) goto resend; else goto done;
- case RS: fprintf(stderr, "page send got RS\n"); goto done;
- case ESC:
- switch(inbuf[1]) {
- case EOT: goto done;
- case '[': if(inbuf[2] == 'p') { ret = 1; goto sent; }
- default: fprintf(stderr, "got unknown ESC code\n");
- goto done;
- }
- }
- sent:
- if(cp) {
- pager = cp;
- goto next_pager;
- }
-
- done:
- /* Logout: EOT CR */
- if (pgsend("\004\r"))
- return(ret);
- pgrecv("\r", 3);
- fputs(ret ? "[Error in delivery]\n" : inbuf, stderr);
- pgrecv("\r", 3);
- return(ret);
- }
-
- pgsend(cp)
- char *cp;
- {
- int i, len = strlen(cp);
-
- nap(40);
- if(vflag)
- fprintf(stderr, "sending: ");
- for (i = 0; i < len; i++) {
- nap(75);
- if(vflag)
- show(cp, 1, stderr);
- if (write(FD, cp, 1) != 1) {
- fprintf(stderr, "pgsend error\n");
- return(-1);
- }
- cp++;
- }
- if(vflag)
- fputc('\n', stderr);
- return(0);
- }
-
- pgrecv(want, secs)
- char *want;
- int secs;
- {
- jmp_buf savebuf;
- int i, size;
- char *cp, *endcp;
-
- bcopy(jmpbuf, savebuf, sizeof(jmpbuf));
- if (setjmp(jmpbuf)) {
- if(vflag)
- fprintf(stderr, "\nrecv: timeout\n");
- bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
- return(0);
- }
- signal(SIGALRM, recvtimeout);
- alarm(secs);
-
- size = strlen(want);
- if(vflag) {
- fprintf(stderr, "recv (want ");
- show(want, size, stderr);
- fprintf(stderr, "/%d): ", size);
- }
- i = size-1;
-
- cp = inbuf; endcp = inbuf+sizeof(inbuf)-1;
- *cp = 0;
- mbuf[0] = 0;
- while (strncmp(mbuf, want, size) != 0 && cp < endcp) {
- bcopy(mbuf+1, mbuf, size);
- if (read(FD, &mbuf[i], 1) != 1)
- goto readerror;
- mbuf[i] &= 0177;
- *cp++ = mbuf[i];
- *cp = 0;
- if(vflag)
- show(&mbuf[i], 1, stderr);
- }
- alarm(0);
- bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
- if (vflag)
- fputs(" -- got it\n", stderr);
- return(cp - inbuf);
- readerror:
- alarm(0);
- bcopy(savebuf, jmpbuf, sizeof(jmpbuf));
- return(-1);
- }
-
- buildpkt(pager, message)
- char *pager, *message;
- {
- char *cp = &packet[0];
- int sum;
-
- *cp++ = STX;
- sum = STX;
-
- cp = addstr(pager, &sum, cp);
- cp = addstr(message, &sum, cp);
-
- *cp++ = ETX;
- sum += ETX;
- *cp++ = '0' + ((sum>>8)&0xf);
- *cp++ = '0' + ((sum>>4)&0xf);
- *cp++ = '0' + (sum&0xf);
- *cp++ = '\r';
- *cp = 0;
- }
-
- static char *
- addstr(s, sump, cp)
- char *s, *cp;
- int *sump;
- {
- char c;
- int sum = *sump;
-
- while(c = *s++) {
- *cp = (isprint(c) ? c : '?');
- sum += *cp;
- cp++;
- }
- *cp++ = '\r';
- sum += '\r';
-
- *sump = sum;
- return(cp);
- }
-